package com.imooc.aspect;

import com.imooc.introduction.LittleUniverse;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Order(1)
public class ServiceAspect {

	/**
	 * 第一个*: 所有返回值类型
	 * ..: package一级子package
	 * 第二个*: 所有的类
	 * .*: 类中的所有方法
	 * (..): 任意参数
	 */
	@Pointcut("execution(* com.imooc.service..*.*(..))")
	public void embed() {}

	@Before("embed()")
	public void before(JoinPoint joinPoint) {
		System.out.println("开始调用@Before " + joinPoint);
	}

	@After("embed()")
	public void after(JoinPoint joinPoint) {
		System.out.println("开始完成@After " + joinPoint);
	}

//	@Around("embed()")
	public Object aroundMe(ProceedingJoinPoint joinpoint) {
		long startTime = System.currentTimeMillis();
		Object returnValue = null;
		System.out.println("开始计时" + joinpoint);

		try {
			returnValue = joinpoint.proceed();
			System.out.println("执行成功, 结束计时" + joinpoint);
		} catch (Throwable throwable) {
			throwable.printStackTrace();
			System.out.println("执行失败, 结束计时" + joinpoint);
		} finally {
			long endTime = System.currentTimeMillis();
			System.out.println("总耗时 " + joinpoint + "[" + (endTime - startTime) + "]ms");
		}

		return returnValue;
	}

//	@AfterReturning(pointcut = "embed()", returning = "returnValue")
	public void afterReturning(JoinPoint joinPoint, Object returnValue) {
		System.out.println("无论是空还是有值都返回 " + joinPoint + " ,返回值[" + returnValue + "]");
	}

//	@AfterThrowing(pointcut = "embed()", throwing = "exception")
	public void afterThrowing(JoinPoint joinPoint, Exception exception) {
		System.out.println("抛出异常通知 " + joinPoint + " " + exception.getMessage());
	}


//	@DeclareParents(value = "com.imooc.controller..*", defaultImpl = com.imooc.introduction.impl.LittleUniverseImpl.class)
	public LittleUniverse littleUniverse;

}
